`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2024/07/24 17:13:18
// Design Name: 
// Module Name: cu
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module cu(
    clk,nop,opcode,funct3,funct7,op_imm,op_wr,op_rd,op_alu,op_b,op_j
    );

    input clk,nop;
    input [6:0] opcode;
    input [2:0] funct3;
    input [6:0] funct7;
    output reg [2:0] op_imm;
    output reg [1:0] op_wr;
    output reg [1:0] op_rd;
    output reg [2:0] op_alu;
    output reg op_b,op_j;

    parameter arith_r=7'b0110011,arith_i=7'b0010011,load=7'b0000011,store=7'b0100011,jal=7'b1101111,jalr=7'b1100111,branch=7'b1100011;

    parameter arith_r_add=10'b0000000000,arith_r_sub=10'b0000100000;
    
    parameter arith_i_add=3'b000;

    always @(posedge clk) begin
        op_imm = 3'bx;
        op_rd = 2'bx;
        op_alu = 3'bx;
        op_wr = 2'bx;
        op_b = 2'b1;
        op_j = 2'b0;
        if(nop!=1'b1) 
            case (opcode)
                arith_r : begin
                    case({funct3,funct7})
                        arith_r_add : begin
                            op_alu = 3'b000;
                        end
                        arith_r_sub : begin
                            op_alu = 3'b001;
                        end
                        default : begin
                            op_alu = 3'bx;
                        end
                    endcase
                    op_imm = 3'b000;
                    op_rd = 2'b00;
                end 
                arith_i : begin
                    case(funct3)
                        arith_i_add : begin
                            op_alu = 3'b000;
                        end
                        default : begin
                            op_alu = 3'bx;
                        end
                    endcase
                    op_imm = 3'b001;
                    op_rd = 2'b00;
                end
                load : begin
                    op_imm = 3'b001;
                    op_rd = 2'b01;
                    op_alu = 3'b000;
                    op_wr = 2'b01;
                end  
                store : begin
                    op_imm = 3'b010;
                    op_alu = 3'b000;
                    op_wr = 2'b0;
                end 
                jal : begin
                    op_imm = 3'b100;
                    op_rd = 2'b10;
                    op_j = 1'b01;
                end
                jalr : begin
                    op_imm = 3'b100;
                    // op_rd = 2'b10;
                    // op_alu = 3'b010;
                    // op_pc = 2'b01;
                end
                branch :  begin
                    op_imm = 3'b011;
                    op_b = 1'b0;
                    op_alu = 3'b000;
                end 
            endcase
    end
endmodule
